#pragma once
#include <iostream>
#include <pthread.h>
#include <functional>

using func_t = std::function<void(void)>;

// template<typename... Args>
// using func_t = std::function<void(Args... args)>;

// template<typename... Args>
class Thread
{
public:
    Thread(const std::string name, func_t func)
        :_name(name), _func(func)
    {}

    static void* routine(void* arg)
    {
        //=============================================================================
        // std::cout << "static void* routine(void* arg)" << std::endl; 
        // ======================================================================

        Thread* ptd = (Thread*)arg;
        ptd->_func();

        return nullptr;
    }

    void Start()
    {
        //=============================================================================
        // std::cout << "Start()::" << _name << std::endl; 
        // ======================================================================

        pthread_create(&_tid, nullptr, routine, this);
    }

    void Join()
    {
        pthread_join(_tid, nullptr);
    }

    std::string GetName()
    {
        return _name;
    }

private:
    pthread_t _tid;
    std::string _name;
    func_t _func;
};
